package edu.fasta.sisinfo2.poker;

import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import edu.fasta.sisinfo2.builders.BuilderJuegos;
import edu.fasta.sisinfo2.builders.CartaAltaBuilder;
import edu.fasta.sisinfo2.builders.ColorBuilder;
import edu.fasta.sisinfo2.builders.DobleParBuilder;
import edu.fasta.sisinfo2.builders.EscaleraBuilder;
import edu.fasta.sisinfo2.builders.EscaleraColorBuilder;
import edu.fasta.sisinfo2.builders.EscaleraRealBuilder;
import edu.fasta.sisinfo2.builders.FullBuilder;
import edu.fasta.sisinfo2.builders.ParBuilder;
import edu.fasta.sisinfo2.builders.PokerBuilder;
import edu.fasta.sisinfo2.builders.TrioBuilder;
import edu.fasta.sisinfo2.juegos.Juego;

public class JugadorImplementacion{

	private int fichas;
	private Apuesta apuesta;
	private Mano mano;
	private String nombre;
	private boolean activo;
	private boolean subioApuesta;
	private Socket ubicacionRed;

	/**
	 * Crea un Nuevo Jugador.
	 * @param nombre Nombre del jugador que se va a crear.
	 */
	public JugadorImplementacion(String nombre, Socket direccion) {
		this.setNombre(nombre);
		this.setFichas(0);
		this.setApuesta(new Apuesta(this));	
		this.setActivo(false);
		this.setMano(new Mano());
		this.setSubioApuesta(false);
		this.setUbicacionRed(direccion);
	}

	/**
	 * Obtiene el mejor juego posible que puede armar el jugador con sus cartas y las de la mesa.
	 * @return {@link Juego} 
	 */
	public Juego obtenerMejorJuego(){

		BuilderJuegos erb = 
				new EscaleraRealBuilder(
						new EscaleraColorBuilder(
								new PokerBuilder(
										new FullBuilder(
												new ColorBuilder(
														new EscaleraBuilder(
																new TrioBuilder(
																		new DobleParBuilder(
																				new ParBuilder(
																						new CartaAltaBuilder())))))))));

		this.getMano().quitarTodasLasCartas();
		
		this.getMano().cargarTodasLasCartas();

		Juego mejorJuego = erb.buildJuego(this.getMano());

		return mejorJuego;		 
	}
	/**
	 * Metodo para agregar fichas al jugador.
	 * @param fichas Cantidad de fichas para agregar.
	 */
	public void agregarFichas(int fichas){
		int f = this.getFichas();
		this.setFichas(f + fichas);
	}
	

	/**
	 * Apuesta All In.
	 * @return Todas las fichas del jugador.
	 */
	public int allIn(){
		int apuestaTodo = this.getFichas();
		this.getApuesta().subirApuesta(apuestaTodo);
		this.setFichas(0);
		return apuestaTodo;
	}
	/**
	 * Apuesta Call.
	 * @return Las fichas apostadas.
	 */
	public int call(int apuestaActual){
		this.getApuesta().subirApuesta(apuestaActual);
		this.setFichas(this.getFichas() - apuestaActual);
		return apuestaActual;
	}
	public int pagarCiegas(int apuestaActual){
		if(this.getFichas() >= apuestaActual){
			this.getApuesta().subirApuesta(apuestaActual);
			this.setFichas(this.getFichas() - apuestaActual);
			return apuestaActual;
		}
		return 0;
	}
	/**
	 * Apuesta Raise
	 * @param cantidad Cantidad de fichas apostadas.
	 * @return Las fichas apostadas.
	 */
	public int raise(String cantidad){
		this.setSubioApuesta(true);
		int numero= Integer.parseInt(cantidad);
		this.getApuesta().subirApuesta(numero);
		this.setFichas(this.getFichas() - numero);

		return numero;
	}
	/**
	 * Check.
	 */
	public void check(){
	}
	/**
	 * Entrega las cartas del jugador.
	 * @return las cartas del jugador.
	 */
	public void fold(){
		
		this.setActivo(false);
		
	}
	/**
	 * @return si el jugador esta activo o no.
	 */
	public boolean isActivo() {
		return activo;
	}
	/**
	 * Cambia el estado del jugador.
	 * @param activo Nuevo estado.
	 */
	public void setActivo(boolean activo) {
		this.activo = activo;
	}
	/**
	 * @return Apuesta del jugador.
	 */
	public Apuesta getApuesta() {
		return apuesta;
	}
	/**
	 * Setea la apuesta del Jugador
	 * @param apuesta Nueva Apuesta.
	 */
	public void setApuesta(Apuesta apuesta) {
		this.apuesta = apuesta;
	}
	/**
	 * @return Nombre del jugador.
	 */
	public String getNombre() {
		return nombre;
	}
	/**
	 * Setea el nombre del jugador. 
	 * @param nombre
	 */
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	/**
	 * @return Fichas del jugador.
	 */
	public int getFichas() {
		return fichas;
	}
	/**
	 * Setea las fichas del jugador.
	 * @param fichas Nueva cantidad de fichas.
	 */
	public void setFichas(int fichas) {
		this.fichas = fichas;
	}
	/**
	 * @return Mano del jugador.
	 */
	public Mano getMano() {
		return mano;
	}
	/**
	 * Setea la mano del jugador.
	 * @param mano Mano nueva.
	 */
	public void setMano(Mano mano) {
		this.mano = mano;
	}
	/**
	 * @return subio o no la apuesta.
	 */
	public boolean isSubioApuesta() {
		return subioApuesta;
	}
	/**
	 * Setea la apuesta del jugador.
	 * @param subioApuesta Nueva apuesta.
	 */
	public void setSubioApuesta(boolean subioApuesta) {
		this.subioApuesta = subioApuesta;
	}
	public Socket getUbicacionRed() {
		return ubicacionRed;
	}
	public void setUbicacionRed(Socket ubicacionRed) {
		this.ubicacionRed = ubicacionRed;
	}

}
